<template>
  <div>
    <el-dialog class="exam-add-dialog" :visible.sync="examAddDialog" width="50%">
      <el-row :gutter="16">
        <el-col :span="4" class="tip"> 考试标题 </el-col>
        <el-col :span="8"><el-input v-model="examInfo.title" placeholder="请输入考试标题"></el-input></el-col>
      </el-row>
      <el-row :gutter="16">
        <el-col :span="4" class="tip"> 选择题分数 </el-col>
        <el-col :span="8"><el-input-number v-model="examInfo.choiceQuScore" :min="1" :max="10"></el-input-number></el-col>
        <el-col :span="4" class="tip"> 填空题分数 </el-col>
        <el-col :span="8"><el-input-number v-model="examInfo.gapFillingQuScore" :min="1" :max="10"></el-input-number></el-col>
      </el-row>
      <el-row :gutter="16">
        <el-col :span="4" class="tip"> 日期范围 </el-col>
        <el-col :span="20">
          <el-date-picker v-model="examInfo.dataRange" value-format="yyyy-MM-dd" type="daterange" range-separator="至" start-placeholder="开始日期" end-placeholder="结束日期"> </el-date-picker>
        </el-col>
      </el-row>
      <el-row :gutter="16">
        <el-col :span="4" class="tip"> 及格分数线 </el-col>
        <el-col :span="8"><el-input-number v-model="examInfo.qualifyScore" :min="1" :max="10"></el-input-number></el-col>
        <el-col :span="4">
          <el-button type="primary" @click="getCourse">选择知识点</el-button>
        </el-col>
        <el-dialog width="30%" title="选择知识点" class="select-knowledge-point-dialog" :visible.sync="selectKnowledgePointDialog" append-to-body>
          <el-select @change="getKnowledgePoint" style="margin-bottom: 10px" v-model="courseId" filterable placeholder="请选择课程">
            <el-option v-for="(item, index) in courseList" :key="index" :label="item.title" :value="item.id"> </el-option>
          </el-select>
          <el-tree @check="checkKnowledgePoint" accordion :data="knowledgePointFromList" show-checkbox></el-tree>
          <span slot="footer" class="dialog-footer">
            <el-button type="primary" @click="selectKnowledgePointDialog = false">确 定</el-button>
          </span>
        </el-dialog>
      </el-row>
      <el-row style="max-height: 45vh; overflow: auto; scrollbar-width: none; margin-bottom: 0">
        <el-row :gutter="16" v-for="(point, index) in knowledgePointList" :key="index">
          <el-col :span="18">
            <el-input v-model="point.knowledgePoint" placeholder="请输入内容"></el-input>
          </el-col>
          <el-col :span="6">
            <el-select v-model="point.type" placeholder="请选择">
              <el-option v-for="(item, index) in questionTypeList" :key="index" :label="item.label" :value="item.value"> </el-option>
            </el-select>
          </el-col>
        </el-row>
      </el-row>
      <span slot="footer" class="dialog-footer">
        <el-button type="primary" @click="publicExam">新增考试</el-button>
      </span>
    </el-dialog>
    <el-dialog title="题目详情" class="exam-qu-show-dialog" @open="getExamQu" :visible.sync="options.examQuShowDialog" width="50%">
      <el-card class="exam-questions" v-for="(question, quIndex) in examQuList" :key="quIndex">
        <div slot="header">
          <span style="display: inline-block; width: 90%">{{ question.question }}</span>
          <!-- <el-button style="float: right; padding: 2px 0" type="text">删除</el-button> -->
          <el-button style="float: right; padding: 2px 0" type="text">{{ question.score + '分' }}</el-button>
        </div>
        <div class="choice" v-if="question.type === 'choice'">
          <p class="" v-for="(item, index) in question.choose" :key="index">{{ item }}</p>
          <p>{{ '答案：' + question.answer }}</p>
        </div>
        <div class="gap-filling" style="padding: 10px 0" v-if="question.type === 'fill'">
          <span v-for="(item, index) in question.answer" :key="index">{{ '答案：' + item }}</span>
        </div>
      </el-card>
    </el-dialog>
    <el-dialog title="学生答题详情" @open="getExamAnswerDetail" :visible.sync="options.examAnswerDetailDialog" width="30%">
      <el-table :data="examAnswerDetailTableData" style="width: 100%">
        <el-table-column type="index" width="100"> </el-table-column>
        <el-table-column prop="name" label="学生姓名"> </el-table-column>
        <el-table-column prop="score" label="学生成绩" width="150"> </el-table-column>
      </el-table>
    </el-dialog>

    <div class="filter-container" style="display: flex; align-items: center; margin-bottom: 20px; flex-wrap: wrap">
      <div style="display: flex; align-items: center">
        <el-button v-if="options.addRoute" type="primary" icon="el-icon-plus" size="small" @click="handleAdd">添加</el-button>
        <el-button v-permission="[options.add.permission]" v-if="options.add && options.add.enable" size="small" type="primary" icon="el-icon-plus" @click="optAdd">添加</el-button>
        <el-button v-permission="[options.edit.permission]" v-if="options.edit && options.edit.enable" :disabled="selectedIds.length === 0" size="small" type="warning" icon="el-icon-edit" @click="optEdit">修改</el-button>
        <el-button v-permission="[options.delete.permission]" v-if="options.delete && options.delete.enable" :disabled="selectedIds.length === 0" size="small" type="danger" icon="el-icon-delete" @click="optDelete">删除</el-button>

        <el-dropdown v-if="options.multiActions && options.multiActions.length > 0 && selectedIds.length > 0" size="small" style="margin-left: 10px" split-button @command="optAction">
          批量操作
          <el-dropdown-menu slot="dropdown">
            <template v-for="(item, index) in options.multiActions">
              <el-dropdown-item v-permission="[item.permission]" :key="index" :command="item">
                {{ item.label }}
              </el-dropdown-item>
            </template>
          </el-dropdown-menu>
        </el-dropdown>

        <slot name="filter-content" />
      </div>
    </div>

    <el-table
      v-loading="listLoading"
      ref="table"
      :data="dataList.records"
      :row-key="getRowKeys"
      :header-cell-style="{
        background: '#f2f3f4',
        color: '#555',
        'font-weight': 'bold',
        'line-height': '32px'
      }"
      border
      fit
      highlight-current-row
      @sort-change="tableSortChange"
      @select="select"
      @select-all="selectAll"
    >
      <el-table-column v-if="options.multi" :reserve-selection="false" align="center" type="selection" width="55" />

      <slot name="data-columns" />
    </el-table>

    <pagination v-show="dataList.total > 0" :page.sync="listQuery.current" :auto-scroll="autoScroll" :total="dataList.total" :limit.sync="listQuery.size" @pagination="getList" />
  </div>
</template>

<script>
import { postData } from '@/api/common'
import Pagination from '@/components/Pagination'
import permission from '@/directive/permission/index.js' // 权限判断指令
import { post } from '@/utils/request'
import { options } from 'dropzone'
import { Message } from 'element-ui'
import axios from 'axios'
import { Loading } from 'element-ui'

export default {
  name: 'PagingTable',
  directives: { permission },
  components: { Pagination },
  // 组件入参
  props: {
    isPerson: {
      type: Boolean,
      default: false
    },
    options: {
      type: Object,
      default: () => {
        return {
          keyId: 'id',
          add: {
            enable: false,
            permission: '',
            router: {}
          },
          edit: {
            enable: false,
            permission: '',
            router: {}
          },
          delete: {
            enable: false,
            permission: '',
            url: ''
          },
          // 批量操作
          multiActions: [],
          // 列表请求URL
          listUrl: '',
          // 删除请求URL
          deleteUrl: '',
          // 启用禁用
          stateUrl: '',
          // 可批量操作
          multi: false
        }
      }
    },

    // 列表查询参数
    listQuery: {
      type: Object,
      default: () => {
        return {
          current: 1,
          size: 10,
          params: {},
          t: 0
        }
      }
    },

    autoScroll: {
      type: Boolean,
      default: true
    }
  },
  data() {
    return {
      // 接口数据返回
      dataList: {
        total: 0
      },
      // 数据加载标识
      listLoading: true,
      // 选定和批量操作
      selectedIds: [],
      selectedRows: [],
      // 显示批量操作
      multiShow: false,
      preDate: 0,
      // 添加考试的 dialog 标识
      examAddDialog: false,
      // 添加知识点得 dialog 标识
      selectKnowledgePointDialog: false,
      // 每一次添加考试的信息
      examInfo: {
        title: '',
        examTypeDictText: '模拟考试',
        openTypeDictText: '完全公开',
        startTime: '',
        endTime: '',
        totalScore: 0,
        qualifyScore: 0,
        state: '正常',
        choiceQuNum: 0,
        choiceQuScore: 2,
        gapFillingQuNum: 0,
        gapFillingQuScore: 2,
        dataRange: '',
        questionList: []
      },
      // 考试试题
      examQuList: [],
      // 所有课程
      courseList: [],
      // 选中得课程ID
      courseId: '',
      // 出题知识点来源
      knowledgePointFromList: [],
      // 出题知识点
      knowledgePointList: [],
      questionTypeList: [
        {
          value: 'choice',
          label: '选择题'
        },
        {
          value: 'fill',
          label: '填空题'
        }
      ],
      // 学生考试答题情况
      examAnswerDetailTableData: []
    }
  },
  watch: {
    // 检测查询变化
    listQuery: {
      handler() {
        const handEvent = this.throttle(this.getList, 500)
        handEvent()
      },
      deep: true
    },

    // 选定监听
    selectedRows: {
      handler(val) {
        // 没有待选定的
        this.selectedIds = val.map(item => this.getRowKeys(item))
        this.$emit('select-changed', { ids: this.selectedIds, objs: val })
      },
      deep: true
    }
  },
  created() {
    this.getList()
  },
  methods: {
    throttle(fn, delay) {
      const that = this
      return function () {
        const nowDate = new Date().getTime()
        if (nowDate - that.preDate > delay) {
          fn.apply(this, arguments)
          that.preDate = nowDate
        }
      }
    },

    // 获取选定的key
    getRowKeys(row) {
      if (this.options.keyId) {
        return row[this.options.keyId]
      }
      return row['id']
    },

    // 添加
    optAdd() {
      if (this.options.add.permission === 'exam:add') {
        this.examAddDialog = true
        return
      }
      // 路由跳转
      if (this.options.add.router) {
        this.$router.push(this.options.add.router)
      }
      this.$emit('add')
    },

    // 修改数据
    optEdit() {
      // 修改最后选定的项目
      const last = this.selectedRows[this.selectedRows.length - 1]
      const id = this.getRowKeys(last)

      // 跳转的
      if (this.options.edit.router) {
        const router = this.options.edit.router
        const params = router.params
        // 追加id参数
        params.id = id
        router.params = params
        this.$router.push(router)
      }
      this.$emit('edit', id, last)
    },

    // 删除
    optDelete() {
      if (this.options.delete.url) {
        // 删除
        this.$confirm('确实要删除吗?', '提示', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        }).then(() => {
          postData(this.options.delete.url, { ids: this.selectedIds }).then(() => {
            this.$message({
              type: 'success',
              message: '删除成功!'
            })
            this.clearSelection()
            this.getList()
          })
        })
      }
      this.$emit('delete', this.selectedIds)
    },

    // 批处理回调
    optAction(item) {
      // 启用
      if (item.value === 'enable') {
        this.handleState(item.url, 0)
        return
      }

      // 禁用
      if (item.value === 'disable') {
        this.handleState(item.url, 1)
        return
      }

      // 改其他状态
      if (item.value === 'state') {
        this.handleState(item.url, item.state)
        return
      }

      // 向外回调的操作
      this.$emit('multi-actions', {
        opt: item.value,
        ids: this.selectedIds,
        objs: this.selectedRows
      })
    },

    // 启用、禁用、修改状态
    handleState(url, state) {
      postData(url, { ids: this.selectedIds, state: state }).then(res => {
        if (res.code === 0) {
          this.$message({
            type: 'success',
            message: '状态修改成功!'
          })
          this.clearSelection()
          // 重新搜索
          this.getList()
        }
      })
    },

    /**
     * 添加数据跳转
     */
    handleAdd() {
      if (this.options.addRoute) {
        this.$router.push({ name: this.options.addRoute, params: {} })
        return
      }
      console.log('未设置添加数据跳转路由！')
    },

    /**
     * 查询数据列表
     */
    getList() {
      this.listLoading = true
      this.listQuery.t = new Date().getTime()
      postData(this.options.listUrl, this.listQuery)
        .then(response => {
          if (this.isPerson) {
            response.data.records.map(item => {
              item.loading = false
            })
          }
          const filteredRecords = response.data.records.filter(item => {
            // 保留 isCurrentVisible 为 true 或 undefined/null 的项
            if (this.options.isCurrentVisible == false) {
              return item.isCurrentVisible == false
            } else return item.isCurrentVisible !== false
            // 或者更严格的写法（仅保留显式为 true 的项）：
            // return item.isCurrentVisible === true;
          })
          response.data.records = filteredRecords
          this.dataList = response.data
          this.listLoading = false
          this.$emit('hasData', true)
          // 延迟回填选定状态
          this.$nextTick(this.toggleSelection)
        })
        .catch(err => {
          this.$emit('hasData', false)
          console.log(err)
          this.listLoading = false
        })
    },

    /**
     * 刷新表格
     */
    refresh() {
      this.clearSelection()
      this.getList()
    },

    // 选择一项时
    select(selection, row) {
      const selected = selection.length && selection.indexOf(row) !== -1
      if (!selected) {
        let index = -1
        this.selectedRows.some((item, i) => {
          if (this.getRowKeys(item) == this.getRowKeys(row)) {
            index = i
          }
        })
        if (index > -1) this.selectedRows.splice(index, 1)
      } else {
        this.selectedRows.push(row)
      }
    },

    // 全选或全不选
    selectAll(selection) {
      if (selection.length > 0) {
        // 全选
        this.dataList.records.forEach(item => {
          if (!this.selectedRows.some(items => this.getRowKeys(items) == this.getRowKeys(item))) {
            this.selectedRows.push(item)
          }
        })
      } else {
        // 全不选
        this.dataList.records.forEach(item => {
          let index = -1
          this.selectedRows.some((items, i) => {
            if (this.getRowKeys(items) == this.getRowKeys(item)) {
              index = i
            }
          })
          if (index > -1) this.selectedRows.splice(index, 1)
        })
      }
    },

    // 服务端数据排序
    tableSortChange(column) {
      this.listQuery.pageNo = 1
      if (column.order === 'descending') {
        this.listQuery.orders = [{ column: column.prop, asc: false }]
      } else {
        this.listQuery.orders = [{ column: column.prop, asc: true }]
      }
      this.getList()
    },

    // 清理勾选状态
    clearSelection() {
      this.$refs.table.clearSelection()
      this.selectedIds = []
      this.selectedRows = []
    },

    // 回填勾选状态
    toggleSelection() {
      const ids = this.selectedRows.map(item => this.getRowKeys(item))
      this.dataList.records.forEach(row => {
        const selected = ids.some(ele => ele === this.getRowKeys(row))
        this.$refs.table.toggleRowSelection(row, selected)
      })
    },

    // 调用题目生成API
    async callGenerateQuestionAPI(data) {
      try {
        const response = await axios.post('http://111.63.183.17:5000/generate_question', data, {
          headers: {
            'Content-Type': 'application/json'
          }
        })

        return response.data
      } catch (error) {
        if (error.response) {
          // 服务器响应了错误状态码
          throw new Error(`服务器错误: ${error.response.status} ${error.response.statusText}`)
        } else if (error.request) {
          // 请求已发出但没有收到响应
          throw new Error('网络错误，请检查网络连接')
        } else {
          // 其他错误
          throw new Error(error.message || '请求失败')
        }
      }
    },
    // 生成试题
    async generatedQuestion() {
      const requestDataList = {}
      this.knowledgePointList.forEach(knowledgePoint => {
        if (knowledgePoint.type === 'choice') {
          this.examInfo.choiceQuNum += 1
        } else if (knowledgePoint.type === 'fill') {
          this.examInfo.gapFillingQuNum += 1
        }
        if (!(knowledgePoint.type in requestDataList)) {
          requestDataList[knowledgePoint.type] = {
            questionType: knowledgePoint.type,
            difficultyLevel: 'difficulty',
            generateMode: 'open',
            data: []
          }
        }
        requestDataList[knowledgePoint.type].data.push({
          content: knowledgePoint.content,
          summary: knowledgePoint.label
        })
      })
      const questionList = []
      for (const questionType in requestDataList) {
        if (requestDataList.hasOwnProperty(questionType)) {
          // 调用出题接口
          const response = await this.callGenerateQuestionAPI(requestDataList[questionType])
          response.forEach(item => {
            item.type = questionType
            if (item.type === 'choice') {
              item.score = this.examInfo.choiceQuScore
            } else if (item.type === 'fill') {
              item.score = this.examInfo.gapFillingQuScore
            }
          })
          questionList.push(...response)
        }
      }
      return questionList
    },
    // 发布考试
    async publicExam() {
      if (this.examInfo.title === '') {
        Message({
          message: '请填写考试标题',
          type: 'error'
        })
        return
      }
      if (this.examInfo.dataRange === '') {
        Message({
          message: '请选择考试的起始时间',
          type: 'error'
        })
        return
      }
      if (this.knowledgePointList.length === 0) {
        Message({
          message: '请选择出题知识点',
          type: 'error'
        })
        return
      }
      let loadingInstance = Loading.service({ fullscreen: true, lock: true, text: '请稍后', background: 'rgba(0, 0, 0, 0.7)' })
      const questionList = await this.generatedQuestion()
      this.examInfo.startTime = this.examInfo.dataRange[0]
      this.examInfo.endTime = this.examInfo.dataRange[1]
      this.examInfo.totalScore = this.examInfo.choiceQuNum * this.examInfo.choiceQuScore + this.examInfo.gapFillingQuNum * this.examInfo.gapFillingQuScore
      const examId = await post('/api/temp/exam', this.examInfo).then(res => {
        this.examInfo.id = res.data
        if ('records' in this.dataList) {
          this.dataList.records.push({ ...this.examInfo })
        } else {
          this.dataList.records = [{ ...this.examInfo }]
        }
        this.examInfo.title = ''
        this.examInfo.dataRange = ''
        return res.data
      })
      await post('/api/temp/exam/qu', { examId, questionList }).then(res => {
        if (res.success) {
          Message({
            message: '考试发布成功',
            type: 'success'
          })
          this.examAddDialog = false
        }
      })
      loadingInstance.close()
    },
    // tree 复选框点击触发事件
    checkKnowledgePoint(node, status) {
      this.knowledgePointList = []
      status.checkedNodes.forEach(item => {
        if (!('children' in item)) {
          this.knowledgePointList.push({
            label: item.label,
            content: item.content,
            knowledgePoint: '<' + item.label + '>' + item.content,
            type: 'choice'
          })
        }
      })
    },
    // 递归处理知识点（暂弃）
    handleKnowledgePointRecursion(knowledgePoints) {
      knowledgePoints.forEach(item => {
        if ('children' in item) {
          this.handleKnowledgePointRecursion(item.children)
        } else {
          this.knowledgePointList.push(item.label + '：' + item.content)
        }
      })
    },
    // 获取课程列表，唤出 selectKnowledgePointDialog
    getCourse() {
      post('/api/course/course/list', {}).then(res => {
        this.courseList = res.data
      })
      this.selectKnowledgePointDialog = true
    },
    // 选中课程，获取知识点
    getKnowledgePoint(courseId) {
      post('/api/course/course/get-knowledge-point', { courseId }).then(res => {
        this.knowledgePointFromList = JSON.parse(res.data.point)
      })
    },
    // 展示题目的 dialog 的打开回调
    async getExamQu() {
      const questionList = await post('/api/temp/exam/qu/list', { examId: this.options.examId }).then(res => {
        return res.data
      })
      this.examQuList = []
      questionList.forEach(item => {
        this.examQuList.push(JSON.parse(item.question))
      })
    },
    // 展示考生答题情况的 dialog 的打开回调
    getExamAnswerDetail() {
      post('/api/temp/exam/record/list', { examId: this.options.examId }).then(res => {
        this.examAnswerDetailTableData = res.data
      })
    }
  }
}
</script>

<style scoped>
::v-deep .filter-container .filter-item {
  margin-left: 10px;
}

::v-deep .filter-container .filter-item:first-child {
  margin-left: 0px;
}

::v-deep .el-button--small {
  padding: 9px;
}

.exam-add-dialog .el-row {
  margin-bottom: 20px;
}
.exam-add-dialog .tip {
  font-size: 20px;
  line-height: 32px;
}

::v-deep .exam-qu-show-dialog > .el-dialog {
  background-color: #f5f6fa;
}
::v-deep .exam-qu-show-dialog .el-card__body {
  padding: 0 20px !important;
}
.exam-qu-show-dialog .el-card {
  margin-bottom: 20px;
}
</style>
